home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 10 / amigaformatcd10.iso / -screenplay- / shareware / mris 1.1 / .mris1_1src.lha / Errors.c < prev    next >
C/C++ Source or Header  |  1996-10-10  |  21KB  |  797 lines

  1. #ifndef INTUITION_IMAGECLASS_H
  2. #include <intuition/imageclass.h>
  3. #endif
  4.  
  5. #ifndef INTUITION_GADGETCLASS_H
  6. #include <intuition/gadgetclass.h>
  7. #endif
  8.  
  9. #ifndef LIBRARIES_IFFPARSE_H
  10. #include <libraries/iffparse.h>
  11. #endif
  12.  
  13. #ifndef INTUITION_ICCLASS_H
  14. #include <intuition/icclass.h>
  15. #endif
  16.  
  17. #include <proto/layers.h>
  18. #include <proto/gadtools.h>
  19.  
  20. #define MYLIB_BOOPSI
  21.  
  22. #include "xmris.h"
  23. #include "Errors.h"
  24. #include "ConfigScreen.h"
  25.  
  26. #include "Catalog.h"
  27.  
  28. /************************************************************************/
  29.  
  30. #define BUTTON_LEFT        0
  31. #define BUTTON_RIGHT        1
  32. #define BUTTON_UP        2
  33. #define BUTTON_DOWN        3
  34. #define SCROLLER_HORIZONTAL    4
  35. #define SCROLLER_VERTICAL    5
  36.  
  37. /************************************************************************/
  38.  
  39. struct Line
  40. {
  41.   struct MinNode Node;
  42.   /* followed by '\0'-terminated text */
  43. };
  44.  
  45. /************************************************************************/
  46.  
  47. struct Window *ErrorWindow;
  48. int ErrorFlag;
  49.  
  50. /************************************************************************/
  51.  
  52. static struct MinList Lines=
  53. {
  54.   (struct MinNode *)&Lines.mlh_Tail,NULL,(struct MinNode *)&Lines.mlh_Head
  55. };
  56. static WORD MaxWidth;
  57. static UWORD LineCount;
  58.  
  59. static struct DrawInfo *DrawInfo;
  60.  
  61. static struct Gadget *Gadgets;
  62. static struct Gadget *VerticalScroller, *HorizontalScroller;
  63.  
  64. static int UnlockScreen;
  65.  
  66. /************************************************************************/
  67.  
  68. static struct TagItem WindowTags[]=
  69. {
  70.   {WA_MinWidth, 0},            /* 0 */
  71.   {WA_MinHeight, 0},            /* 1 */
  72.   {WA_MaxWidth, ~0},            /* 2 */
  73.   {WA_MaxHeight, ~0},            /* 3 */
  74.   {WA_CustomScreen, (ULONG)NULL},    /* 4 */
  75.   {WA_Width, 0},            /* 5 */
  76.   {WA_Height, 0},            /* 6 */
  77.   {WA_Left, ~0},            /* 7 */
  78.   {WA_Top, ~0},                /* 8 */
  79.   {WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH | WFLG_NEWLOOKMENUS | WFLG_SIZEBBOTTOM | WFLG_SIZEBRIGHT},
  80.   {TAG_DONE}
  81. };
  82.  
  83. /************************************************************************/
  84.  
  85. void CloseErrorWindow()
  86.  
  87. {
  88.   if ((struct Screen *)WindowTags[4].ti_Data!=NULL)
  89.     {
  90.       if (DrawInfo!=NULL)
  91.     {
  92.       if (Gadgets!=NULL)
  93.         {
  94.           if (ErrorWindow!=NULL)
  95.         {
  96.           struct Menu *Menustrip;
  97.  
  98.           if ((Menustrip=ErrorWindow->MenuStrip)!=NULL)
  99.             {
  100.               ClearMenuStrip(ErrorWindow);
  101.               FreeVisualInfo(GTMENU_USERDATA(Menustrip));
  102.               FreeMenus(Menustrip);
  103.             }
  104.           GS_WindowWakeup(ErrorWindow);
  105.           assert(WindowTags[5].ti_Tag==WA_Width);
  106.           assert(WindowTags[6].ti_Tag==WA_Height);
  107.           LockLayerInfo(ErrorWindow->WLayer->LayerInfo);
  108.           WindowTags[5].ti_Data=ErrorWindow->Width;
  109.           WindowTags[6].ti_Data=ErrorWindow->Height;
  110.           WindowTags[7].ti_Data=ErrorWindow->LeftEdge;
  111.           WindowTags[8].ti_Data=ErrorWindow->TopEdge;
  112.           UnlockLayerInfo(ErrorWindow->WLayer->LayerInfo);
  113.           CloseWindowSafely(ErrorWindow);
  114.           ErrorWindow=NULL;
  115.         }
  116.           while (Gadgets!=NULL)
  117.         {
  118.           struct Gadget *Next;
  119.  
  120.           DisposeObject(Gadgets->UserData);
  121.           Next=Gadgets->NextGadget;
  122.           DisposeObject(Gadgets);
  123.           Gadgets=Next;
  124.         }
  125.         }
  126.       FreeScreenDrawInfo((struct Screen *)WindowTags[4].ti_Data,DrawInfo);
  127.     }
  128.       if (UnlockScreen)
  129.     {
  130.       UnlockPubScreen(NULL,(struct Screen *)WindowTags[4].ti_Data);
  131.     }
  132.       WindowTags[4].ti_Data=(ULONG)NULL;
  133.     }
  134. }
  135.  
  136. /************************************************************************/
  137. /*                                    */
  138. /* Measure width of all text lines, to find maximum width        */
  139. /*                                    */
  140. /************************************************************************/
  141.  
  142. static void CalcMaxWidth(void)
  143.  
  144. {
  145.   struct Line *Line;
  146.  
  147.   for (Line=(struct Line *)Lines.mlh_Head; Line->Node.mln_Succ!=NULL; Line=(struct Line *)Line->Node.mln_Succ)
  148.     {
  149.       WORD Width;
  150.  
  151.       Width=TextLength(ErrorWindow->RPort,(char *)(Line+1),strlen((char *)(Line+1)));
  152.       if (Width>MaxWidth)
  153.     {
  154.       MaxWidth=Width;
  155.     }
  156.     }
  157. }
  158.  
  159. /************************************************************************/
  160. /*                                    */
  161. /* Create & install the clipping region                    */
  162. /*                                    */
  163. /************************************************************************/
  164.  
  165. static int InstallClipping(void)
  166.  
  167. {
  168.   struct Region *Region;
  169.  
  170.   if ((Region=NewRegion())!=NULL)
  171.     {
  172.       struct Rectangle Rectangle;
  173.  
  174.       Rectangle.MinX=ErrorWindow->BorderLeft+ErrorWindow->RPort->TxHeight;
  175.       Rectangle.MaxX=ErrorWindow->Width-ErrorWindow->BorderRight-ErrorWindow->RPort->TxHeight-1;
  176.       Rectangle.MinY=ErrorWindow->BorderTop+ErrorWindow->RPort->TxHeight/2;
  177.       Rectangle.MaxY=ErrorWindow->Height-ErrorWindow->BorderBottom-ErrorWindow->RPort->TxHeight/2-1;
  178.       if (OrRectRegion(Region,&Rectangle))
  179.     {
  180.       InstallClipRegion(ErrorWindow->WLayer,Region);
  181.       return TRUE;
  182.     }
  183.       DisposeRegion(Region);
  184.     }
  185.   return FALSE;
  186. }
  187.  
  188. /************************************************************************/
  189.  
  190. static void RemoveClipping(void)
  191.  
  192. {
  193.   DisposeRegion(InstallClipRegion(ErrorWindow->WLayer,NULL));
  194. }
  195.  
  196. /************************************************************************/
  197. /*                                    */
  198. /* Redraw the full window.                        */
  199. /* This just does the rendering, no clipping!                */
  200. /*                                    */
  201. /************************************************************************/
  202.  
  203. static void DrawWindow(void)
  204.  
  205. {
  206.   WORD Y, YMax, X, XMax;
  207.   struct RastPort *RastPort;
  208.   struct Line *Current;
  209.  
  210.   RastPort=ErrorWindow->RPort;
  211.   YMax=ErrorWindow->Height-ErrorWindow->BorderBottom-RastPort->TxHeight/2;
  212.   SetABPenDrMd(RastPort,DrawInfo->dri_Pens[TEXTPEN],DrawInfo->dri_Pens[BACKGROUNDPEN],JAM2);
  213.   YMax=ErrorWindow->Height-ErrorWindow->BorderBottom-RastPort->TxHeight/2;
  214.   Y=ErrorWindow->BorderTop+RastPort->TxHeight/2-AttrGet((Object *)VerticalScroller,PGA_Top);
  215.   Current=(struct Line *)Lines.mlh_Head;
  216.   while (Y<0)
  217.     {
  218.       assert(Current->Node.mln_Succ!=NULL);
  219.       Current=(struct Line *)Current->Node.mln_Succ;
  220.       Y+=RastPort->TxHeight;
  221.     }
  222.   X=ErrorWindow->BorderLeft+RastPort->TxHeight-AttrGet((Object *)HorizontalScroller,PGA_Top);
  223.   XMax=ErrorWindow->Width-ErrorWindow->BorderRight-RastPort->TxHeight;
  224.   while (Current->Node.mln_Succ!=NULL && Y<=YMax)
  225.     {
  226.       Move(RastPort,X,Y+RastPort->TxBaseline);
  227.       Text(RastPort,(char *)(Current+1),strlen((char *)(Current+1)));
  228.       if (RastPort->cp_x<=XMax)
  229.     {
  230.       SetAPen(RastPort,DrawInfo->dri_Pens[BACKGROUNDPEN]);
  231.       RectFill(RastPort,RastPort->cp_x,Y,XMax,Y+RastPort->TxHeight-1);
  232.       SetAPen(RastPort,DrawInfo->dri_Pens[TEXTPEN]);
  233.     }
  234.       Y+=RastPort->TxHeight;
  235.       Current=(struct Line *)Current->Node.mln_Succ;
  236.     }
  237. }
  238.  
  239. /************************************************************************/
  240.  
  241. static void RedrawWindow(void)
  242.  
  243. {
  244.   LockLayer(0,ErrorWindow->WLayer);
  245.   if (InstallClipping())
  246.     {
  247.       DrawWindow();
  248.       RemoveClipping();
  249.     }
  250.   UnlockLayer(ErrorWindow->WLayer);
  251. }
  252.  
  253. /************************************************************************/
  254.  
  255. static INLINE void MakeMenu(void)
  256.  
  257. {
  258.   static struct NewMenu NewMenu[]=
  259.     {
  260.       {NM_TITLE,(STRPTR)MSG_GAME_MENU,NULL,0,0,NULL},
  261.       {NM_ITEM,(STRPTR)MSG_GAME_FLUSHERRORS_MENU,NULL,0,0,(APTR)MSG_GAME_FLUSHERRORS_MENU},
  262.       {NM_ITEM,NM_BARLABEL,NULL,0,0,NULL},
  263.       {NM_ITEM,(STRPTR)MSG_GAME_QUIT_MENU,NULL,0,0,(APTR)MSG_GAME_QUIT_MENU},
  264.       {NM_TITLE,(STRPTR)MSG_CONFIG_MENU,NULL,0,0,NULL},
  265.       {NM_ITEM,(STRPTR)MSG_CONFIG_DISPLAY_SCREEN_MENU,NULL,0,0,(APTR)MSG_CONFIG_DISPLAY_SCREEN_MENU},
  266.       {NM_END}
  267.     };
  268.   struct Menu *Menustrip;
  269.  
  270.   if ((Menustrip=CreateMenustrip(NewMenu))!=NULL)
  271.     {
  272.       APTR VisualInfo;
  273.  
  274.       assert(WindowTags[4].ti_Tag==WA_CustomScreen);
  275.       if ((VisualInfo=GetVisualInfoA((struct Screen *)WindowTags[4].ti_Data,NULL))!=NULL)
  276.     {
  277.       static struct TagItem TagList[]=
  278.         {
  279.           {GTMN_NewLookMenus, TRUE},
  280.           {TAG_DONE}
  281.         };
  282.  
  283.       if (LayoutMenusA(Menustrip,VisualInfo,TagList))
  284.         {
  285.           SetMenuStrip(ErrorWindow,Menustrip);
  286.           GTMENU_USERDATA(Menustrip)=VisualInfo;
  287.           return;
  288.         }
  289.       FreeVisualInfo(VisualInfo);
  290.     }
  291.       FreeMenus(Menustrip);
  292.     }
  293. }
  294.  
  295. /************************************************************************/
  296.  
  297. static struct Image *MakeImage(struct Screen *Screen, ULONG Type)
  298.  
  299. {
  300.   return (struct Image *)NewObject(NULL,BOOPSI_sysiclass,
  301.                    SYSIA_Which, Type,
  302.                    SYSIA_DrawInfo, DrawInfo,
  303.                    SYSIA_Size, (Screen->Flags & SCREENHIRES) ? SYSISIZE_MEDRES : SYSISIZE_LOWRES,
  304.                    TAG_DONE);
  305. }
  306.  
  307. /************************************************************************/
  308.  
  309. static void UpdateScrollers(void)
  310.  
  311. {
  312.   SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,
  313.          PGA_Total, LineCount*ErrorWindow->RPort->TxHeight,
  314.          PGA_Visible, ErrorWindow->Height-ErrorWindow->BorderTop-ErrorWindow->BorderBottom-2*(ErrorWindow->RPort->TxHeight/2),
  315.          TAG_DONE);
  316.   SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,
  317.          PGA_Total, MaxWidth,
  318.          PGA_Visible, ErrorWindow->Width-ErrorWindow->BorderLeft-ErrorWindow->BorderRight-2*ErrorWindow->RPort->TxHeight,
  319.          TAG_DONE);
  320. }
  321.  
  322. /************************************************************************/
  323.  
  324. void OpenErrorWindow(void)
  325.  
  326. {
  327.   if (ErrorWindow==NULL)
  328.     {
  329.       struct Screen *Screen;
  330.  
  331.       if (display.Screen!=NULL)
  332.     {
  333.       Screen=display.Screen->Screen;
  334.       UnlockScreen=FALSE;
  335.     }
  336.       else
  337.     {
  338.       Screen=LockPubScreen(NULL);
  339.       UnlockScreen=TRUE;
  340.     }
  341.       assert(WindowTags[4].ti_Tag==WA_CustomScreen);
  342.       WindowTags[4].ti_Data=(ULONG)Screen;
  343.       if (Screen!=NULL)
  344.     {
  345.       if ((DrawInfo=GetScreenDrawInfo(Screen))!=NULL)
  346.         {
  347.           struct Image *Image;
  348.  
  349.           if ((Image=MakeImage(Screen,SIZEIMAGE))!=NULL)
  350.         {
  351.           WORD SizingWidth, SizingHeight;
  352.  
  353.           SizingWidth=Image->Width;
  354.           SizingHeight=Image->Height;
  355.           DisposeObject(Image);
  356.           if ((Image=MakeImage(Screen,RIGHTIMAGE))!=NULL)
  357.             {
  358.               struct Gadget *Gadget;
  359.  
  360.               Gadgets=Gadget=NewObject(NULL,BOOPSI_buttongclass,
  361.                            GA_RelRight, 1-(SizingWidth+Image->Width),
  362.                            GA_RelBottom, 1-Image->Height,
  363.                            GA_BottomBorder, TRUE,
  364.                            GA_Image, Image,
  365.                            GA_UserData, Image,
  366.                            ICA_TARGET, ICTARGET_IDCMP,
  367.                            GA_ID, BUTTON_RIGHT,
  368.                            TAG_DONE);
  369.               if (Gadget!=NULL && (Image=MakeImage(Screen,LEFTIMAGE))!=NULL)
  370.             {
  371.               Gadget=NewObject(NULL,BOOPSI_buttongclass,
  372.                        GA_Previous, Gadget,
  373.                        GA_RelRight, Gadget->LeftEdge-Image->Width,
  374.                        GA_RelBottom, Gadget->TopEdge,
  375.                        GA_BottomBorder, TRUE,
  376.                        GA_Image, Image,
  377.                        GA_UserData, Image,
  378.                        ICA_TARGET, ICTARGET_IDCMP,
  379.                        GA_ID, BUTTON_LEFT,
  380.                        TAG_DONE);
  381.               if (Gadget!=NULL)
  382.                 {
  383.                   Image=NULL;
  384.                   Gadget=NewObject(NULL,BOOPSI_propgclass,
  385.                            GA_Previous, Gadget,
  386.                            PGA_Freedom, FREEHORIZ,
  387.                            PGA_NewLook, TRUE,
  388.                            PGA_Borderless, TRUE,
  389.                            GA_Left, Screen->WBorLeft,
  390.                            GA_RelBottom, -SizingHeight+Screen->WBorBottom/2+2,
  391.                            GA_RelWidth, Gadget->LeftEdge-Screen->WBorLeft-1,
  392.                            GA_Height, SizingHeight-Screen->WBorBottom-2,
  393.                            GA_BottomBorder, TRUE,
  394.                            GA_UserData, NULL,
  395.                            ICA_TARGET, ICTARGET_IDCMP,
  396.                            GA_ID, SCROLLER_HORIZONTAL,
  397.                            TAG_DONE);
  398.                   HorizontalScroller=Gadget;
  399.                   if (Gadget!=NULL && (Image=MakeImage(Screen,DOWNIMAGE))!=NULL)
  400.                 {
  401.                   Gadget=NewObject(NULL,BOOPSI_buttongclass,
  402.                            GA_Previous, Gadget,
  403.                            GA_RelRight, 1-Image->Width,
  404.                            GA_RelBottom, 1-(SizingHeight+Image->Height),
  405.                            GA_RightBorder, TRUE,
  406.                            GA_Image, Image,
  407.                            GA_UserData, Image,
  408.                            ICA_TARGET, ICTARGET_IDCMP,
  409.                            GA_ID, BUTTON_DOWN,
  410.                            TAG_DONE);
  411.                   if (Gadget!=NULL && (Image=MakeImage(Screen,UPIMAGE))!=NULL)
  412.                     {
  413.                       Gadget=NewObject(NULL,BOOPSI_buttongclass,
  414.                                GA_Previous, Gadget,
  415.                                GA_RelRight, Gadget->LeftEdge,
  416.                                GA_RelBottom, Gadget->TopEdge-Image->Height,
  417.                                GA_RightBorder, TRUE,
  418.                                GA_Image, Image,
  419.                                GA_UserData, Image,
  420.                                ICA_TARGET, ICTARGET_IDCMP,
  421.                                GA_ID, BUTTON_UP,
  422.                                TAG_DONE);
  423.                       if (Gadget!=NULL)
  424.                     {
  425.                       WORD TopBorder;
  426.  
  427.                       Image=NULL;
  428.                       TopBorder=Screen->WBorTop+DrawInfo->dri_Font->tf_YSize+1;
  429.                       Gadget=NewObject(NULL,BOOPSI_propgclass,
  430.                                GA_Previous, Gadget,
  431.                                PGA_NewLook, TRUE,
  432.                                PGA_Borderless, TRUE,
  433.                                PGA_Top, MAX_WORD,
  434.                                GA_Top, TopBorder,
  435.                                GA_RelRight, Screen->WBorRight/2+2-SizingWidth,
  436.                                GA_RelHeight, Gadget->TopEdge-TopBorder-1,
  437.                                GA_Width, SizingWidth-Screen->WBorRight-2,
  438.                                GA_RightBorder, TRUE,
  439.                                GA_UserData, NULL,
  440.                                GA_ID, SCROLLER_VERTICAL,
  441.                                ICA_TARGET, ICTARGET_IDCMP,
  442.                                TAG_DONE);
  443.                       VerticalScroller=Gadget;
  444.                       if (Gadget!=NULL)
  445.                         {
  446.                           assert(WindowTags[0].ti_Tag==WA_MinWidth);
  447.                           WindowTags[0].ti_Data=10*DrawInfo->dri_Font->tf_YSize-HorizontalScroller->Width;
  448.                           assert(WindowTags[1].ti_Tag==WA_MinHeight);
  449.                           WindowTags[1].ti_Data=DrawInfo->dri_Font->tf_YSize-VerticalScroller->Height;
  450.                           if (WindowTags[1].ti_Data<3*DrawInfo->dri_Font->tf_YSize)
  451.                         {
  452.                           WindowTags[1].ti_Data=3*DrawInfo->dri_Font->tf_YSize;
  453.                         }
  454.                           assert(WindowTags[5].ti_Tag==WA_Width);
  455.                           if (WindowTags[5].ti_Data<WindowTags[0].ti_Data)
  456.                         {
  457.                           WindowTags[5].ti_Data=WindowTags[0].ti_Data+15*DrawInfo->dri_Font->tf_YSize;
  458.                         }
  459.                           assert(WindowTags[6].ti_Tag==WA_Height);
  460.                           if (WindowTags[6].ti_Data<WindowTags[1].ti_Data)
  461.                         {
  462.                           WindowTags[6].ti_Data=WindowTags[1].ti_Data;
  463.                         }
  464.                           assert(WindowTags[7].ti_Tag==WA_Left);
  465.                           assert(WindowTags[8].ti_Tag==WA_Top);
  466.                           if (WindowTags[7].ti_Data==~0)
  467.                         {
  468.                           ULONG IntuiLock;
  469.  
  470.                           IntuiLock=LockIBase(0);
  471.                           WindowTags[7].ti_Data=Screen->MouseX;
  472.                           WindowTags[8].ti_Data=Screen->MouseY;
  473.                           UnlockIBase(IntuiLock);
  474.                           WindowTags[7].ti_Data-=WindowTags[5].ti_Data/2;
  475.                           WindowTags[8].ti_Data-=WindowTags[6].ti_Data/2;
  476.                         }
  477.                           ErrorWindow=OpenWindowTags(NULL,
  478.                                      WA_Title, GetString(MSG_ERRORS_TITLE),
  479.                                      WA_Gadgets, Gadgets,
  480.                                      TAG_MORE, WindowTags);
  481.                           if (ErrorWindow!=NULL)
  482.                         {
  483.                           SetFont(ErrorWindow->RPort,DrawInfo->dri_Font);
  484.                           ErrorWindow->UserPort=&WindowPort;
  485.                           if (ModifyIDCMP(ErrorWindow,(IDCMP_REFRESHWINDOW |
  486.                                            IDCMP_CLOSEWINDOW |
  487.                                            IDCMP_IDCMPUPDATE |
  488.                                            IDCMP_MENUPICK |
  489.                                            IDCMP_NEWSIZE)))
  490.                             {
  491.                               MakeMenu();
  492.                               CalcMaxWidth();
  493.                               LockLayer(0,ErrorWindow->WLayer);
  494.                               if (InstallClipping())
  495.                             {
  496.                               UpdateScrollers();
  497.                               DrawWindow();
  498.                               RemoveClipping();
  499.                             }
  500.                               UnlockLayer(ErrorWindow->WLayer);
  501.                               if (MiscState.Sleep)
  502.                             {
  503.                               GS_WindowSleep(ErrorWindow);
  504.                             }
  505.                               return;
  506.                             }
  507.                         }
  508.                         }
  509.                     }
  510.                     }
  511.                 }
  512.                 }
  513.             }
  514.             }
  515.           DisposeObject(Image);
  516.         }
  517.         }
  518.       CloseErrorWindow();
  519.     }
  520.     }
  521. }
  522.  
  523. /************************************************************************/
  524.  
  525. void DisplayError(LONG TemplateID, ...)
  526.  
  527. {
  528.   char String[ERRORSTRING_LENGTH];
  529.   char *Error;
  530.   ULONG Length;
  531.  
  532.   if (TemplateID!=0)
  533.     {
  534.       Error=GS_FormatString(GetString(TemplateID),(&TemplateID)+1,&Length,Locale);
  535.     }
  536.   else
  537.     {
  538.       Error=ErrorString(String,*(&TemplateID+1));
  539.       Length=strlen(Error);
  540.     }
  541.   if (Error!=NULL)
  542.     {
  543.       struct Line *Line;
  544.  
  545.       if ((Line=GS_MemoryAlloc(sizeof(*Line)+Length+1))!=NULL)
  546.     {
  547.       strcpy((char *)(Line+1),Error);
  548.       AddTail((struct List *)&Lines,(struct Node *)&Line->Node);
  549.       LineCount++;
  550.       if (ErrorWindow!=NULL)
  551.         {
  552.           if (LineCount*ErrorWindow->RPort->TxHeight+2*(ErrorWindow->RPort->TxHeight/2)+ErrorWindow->BorderTop+ErrorWindow->BorderBottom>MAX_WORD)
  553.         {
  554.           GS_MemoryFree(RemHead((struct List *)&Lines));
  555.           CalcMaxWidth();
  556.         }
  557.           else
  558.         {
  559.           WORD Width;
  560.  
  561.           Width=TextLength(ErrorWindow->RPort,(char *)(Line+1),Length);
  562.           if (Width>MaxWidth)
  563.             {
  564.               MaxWidth=Width;
  565.             }
  566.         }
  567.           UpdateScrollers();
  568.         }
  569.       if (ErrorWindow!=NULL)
  570.         {
  571.           SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,MAX_WORD,TAG_DONE);
  572.           SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,0,TAG_DONE);
  573.           RedrawWindow();
  574.         }
  575.       else
  576.         {
  577.           OpenErrorWindow();
  578.         }
  579.       ErrorFlag=TRUE;
  580.     }
  581.       if (TemplateID!=0)
  582.     {
  583.       GS_MemoryFree(Error);
  584.     }
  585.     }
  586. }
  587.  
  588. /************************************************************************/
  589.  
  590. void FreeErrors(void)
  591.  
  592. {
  593.   struct Line *Line;
  594.  
  595.   while ((Line=(struct Line *)RemHead((struct List *)&Lines))!=NULL)
  596.     {
  597.       GS_MemoryFree(Line);
  598.     }
  599. }
  600.  
  601. /************************************************************************/
  602. /*                                    */
  603. /* Currently the DOS error codes (ERROR_#?), IFF error codes        */
  604. /* (IFFERR_#?) and screen error codes (OSERR_#?) are supported.        */
  605. /*                                    */
  606. /************************************************************************/
  607.  
  608. char *ErrorString(char *String, LONG ErrorCode)
  609.  
  610. {
  611.   if (ErrorCode<0)
  612.     {
  613.       /* IFF error */
  614.  
  615.       switch (ErrorCode)
  616.     {
  617.     case IFFERR_NOTIFF:
  618.       return GetString(MSG_IFFERR_NOTIFF);
  619.  
  620.     case IFFERR_NOSCOPE:
  621.     case IFFERR_MANGLED:
  622.     case IFFERR_SYNTAX:
  623.       return GetString(MSG_IFFERR_INVALIDIFF);
  624.  
  625.     case IFFERR_NOMEM:
  626.       ErrorCode=ERROR_NO_FREE_STORE;
  627.       break;
  628.  
  629.     case IFFERR_READ:
  630.       return GetString(MSG_IFFERR_READ);
  631.  
  632.     case IFFERR_WRITE:
  633.       return GetString(MSG_IFFERR_WRITE);
  634.  
  635.     case IFFERR_SEEK:
  636.       return GetString(MSG_IFFERR_SEEK);
  637.     }
  638.     }
  639.  
  640.   if (ErrorCode<100)
  641.     {
  642.       /* screen error code */
  643.  
  644.       switch (ErrorCode)
  645.     {
  646.     case OSERR_NOMEM:
  647.       ErrorCode=ERROR_NO_FREE_STORE;
  648.       break;
  649.  
  650.     case OSERR_NOCHIPMEM:
  651.       return GetString(MSG_OSERR_NOCHIPMEM);
  652.  
  653.     case OSERR_NOMONITOR:
  654.     case OSERR_NOCHIPS:
  655.     case OSERR_UNKNOWNMODE:
  656.     case OSERR_NOTAVAILABLE:
  657.       return GetString(MSG_OSERR_INVALIDMODE);
  658.  
  659. #ifdef DEBUG
  660.     case OSERR_PUBNOTUNIQUE:
  661.       assert(FALSE);
  662.       break;
  663. #endif
  664.  
  665.     case OSERR_TOODEEP:
  666.       return GetString(MSG_OSERR_TOODEEP);
  667.     }
  668.     }
  669.  
  670.   if (ErrorCode==ERROR_UNKNOWN || ErrorCode==0)
  671.     {
  672.       return GetString(MSG_ERROR_UNKNOWN);
  673.     }
  674.  
  675.   /* DOS error code */
  676.   Fault(ErrorCode,NULL,String,ERRORSTRING_LENGTH);
  677.   return String;
  678. }
  679.  
  680. /************************************************************************/
  681.  
  682. void ProcessErrorWindow(struct IntuiMessage *Message)
  683.  
  684. {
  685.   switch (Message->Class)
  686.     {
  687.     case IDCMP_CLOSEWINDOW:
  688.       ReplyMsg(&Message->ExecMessage);
  689.       CloseErrorWindow();
  690.       return;
  691.  
  692.     case IDCMP_MENUPICK:
  693.       {
  694.     UWORD Selection;
  695.  
  696.     Selection=Message->Code;
  697.     while (Selection!=MENUNULL && !global.quit)
  698.       {
  699.         struct MenuItem *Item;
  700.  
  701.         Item=ItemAddress(ErrorWindow->MenuStrip,Selection);
  702.         switch ((ULONG)GTMENUITEM_USERDATA(Item))
  703.           {
  704.           case MSG_GAME_QUIT_MENU:
  705.         global.quit=TRUE;
  706.         break;
  707.  
  708.           case MSG_CONFIG_DISPLAY_SCREEN_MENU:
  709.         OpenConfigScreen();
  710.         break;
  711.  
  712.           case MSG_GAME_FLUSHERRORS_MENU:
  713.         FreeErrors();
  714.         goto Redraw;
  715.           }
  716.         Selection=Item->NextSelect;
  717.       }
  718.       }
  719.       break;
  720.  
  721.     case IDCMP_REFRESHWINDOW:
  722.       LockLayerInfo(ErrorWindow->WLayer->LayerInfo);
  723.       if (InstallClipping())
  724.     {
  725.       BeginRefresh(ErrorWindow);
  726.       DrawWindow();
  727.       EndRefresh(ErrorWindow,TRUE);
  728.       RemoveClipping();
  729.     }
  730.       UnlockLayerInfo(ErrorWindow->WLayer->LayerInfo);
  731.       break;
  732.  
  733.     case IDCMP_NEWSIZE:
  734.     Redraw:
  735.       LockLayer(0,ErrorWindow->WLayer);
  736.       SetABPenDrMd(ErrorWindow->RPort,DrawInfo->dri_Pens[BACKGROUNDPEN],0,JAM1);
  737.       RectFill(ErrorWindow->RPort,
  738.            ErrorWindow->BorderLeft,
  739.            ErrorWindow->BorderTop,
  740.            ErrorWindow->Width-ErrorWindow->BorderRight-1,
  741.            ErrorWindow->Height-ErrorWindow->BorderBottom-1);
  742.       if (InstallClipping())
  743.     {
  744.       UpdateScrollers();
  745.       DrawWindow();
  746.       RemoveClipping();
  747.     }
  748.       UnlockLayer(ErrorWindow->WLayer);
  749.       break;
  750.  
  751.     case IDCMP_IDCMPUPDATE:
  752.       switch (GetTagData(GA_ID,0,(struct TagItem *)Message->IAddress))
  753.     {
  754.     case SCROLLER_HORIZONTAL:
  755.     case SCROLLER_VERTICAL:
  756.       RedrawWindow();
  757.       break;
  758.  
  759.     case BUTTON_LEFT:
  760.       {
  761.         WORD Top;
  762.  
  763.         if ((Top=(WORD)AttrGet((Object *)HorizontalScroller,PGA_Top))>0)
  764.           {
  765.         SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,Top-1,TAG_DONE);
  766.         RedrawWindow();
  767.           }
  768.       }
  769.       break;
  770.  
  771.     case BUTTON_RIGHT:
  772.       SetGadgetAttrs(HorizontalScroller,ErrorWindow,NULL,PGA_Top,AttrGet((Object *)HorizontalScroller,PGA_Top)+1,TAG_DONE);
  773.       RedrawWindow();
  774.       break;
  775.  
  776.     case BUTTON_UP:
  777.       {
  778.         WORD Top;
  779.  
  780.         if ((Top=(WORD)AttrGet((Object *)VerticalScroller,PGA_Top))>0)
  781.           {
  782.         SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,Top-1,TAG_DONE);
  783.         RedrawWindow();
  784.           }
  785.       }
  786.       break;
  787.  
  788.     case BUTTON_DOWN:
  789.       SetGadgetAttrs(VerticalScroller,ErrorWindow,NULL,PGA_Top,AttrGet((Object *)VerticalScroller,PGA_Top)+1,TAG_DONE);
  790.       RedrawWindow();
  791.       break;
  792.     }
  793.       break;
  794.     }
  795.   ReplyMsg(&Message->ExecMessage);
  796. }
  797.